package main

import (
	"crypto/cipher"
	"crypto/ecdsa"
	"encoding/hex"
	"errors"
	"github.com/emmansun/gmsm/padding"
	"github.com/emmansun/gmsm/sm2"
	"github.com/emmansun/gmsm/sm4"
)

// SM3Digest represents the SM3 hashing algorithm.
type SM3Digest struct{}

// SM4Utils represents the SM4 encryption/decryption algorithm.
type SM4Utils struct {
	secretKey string
	hexString bool
}

// verifySM2Signature 模拟验证 SM2 签名的函数
func verifySM2Signature(PK *ecdsa.PublicKey, data, signature string) bool {
	// 在这里实现 SM2 签名的验证逻辑
	decodeString, err := hex.DecodeString(signature)
	if err != nil {
		panic(err)
	}
	return sm2.VerifyASN1WithSM2(PK, defaultUID, []byte(data), decodeString)
}

// decryptDataECB 模拟 SM4 CBC 解密的函数
func (s *SM4Utils) decryptDataECB(cipherText string) (string, error) {
	// 在这里实现 SM4 CBC 解密的逻辑
	cbc := Sm4DecryptCBC(cipherText, s.secretKey)
	if cbc == "" {
		return "", errors.New("呃呃了")
	}
	return cbc, nil
}

func Sm4DecryptCBC(cipherText, keyIn string) string {
	key, _ := hex.DecodeString(keyIn)
	ciphertext, _ := hex.DecodeString(cipherText)

	block, err := sm4.NewCipher(key)
	if err != nil {
		panic(err)
	}

	// The IV needs to be unique, but not secure. Therefore it's common to
	// include it at the beginning of the ciphertext.
	if len(ciphertext) < sm4.BlockSize {
		panic("ciphertext too short")
	}
	iv := ciphertext[:sm4.BlockSize]
	ciphertext = ciphertext[sm4.BlockSize:]

	mode := cipher.NewCBCDecrypter(block, iv)

	// CryptBlocks can work in-place if the two arguments are the same.
	mode.CryptBlocks(ciphertext, ciphertext)

	// Unpad plaintext
	pkcs7 := padding.NewPKCS7Padding(sm4.BlockSize)
	ciphertext, err = pkcs7.Unpad(ciphertext)
	if err != nil {
		panic(err)
	}

	//fmt.Printf("_________________________________%s\n", ciphertext)
	return string(ciphertext)
}
